class MultiTieredTests extends CloudToolsBaseTests{
	
	def grailsApplication
	def cloudToolsService
	
	void setUp(){
		//programatically turn the cluster spec into a MultipleInstancesTopology and launch it
		grailsApplication.config.cloudTools.clusterSpec.topology = "MultipleInstancesTopology"
		grailsApplication.config.cloudTools.clusterSpec.tomcats(1)
		grailsApplication.config.cloudTools.clusterSpec.slaves(1)
		
		cloudToolsService.withClusterManager {clusterManager, clusterName ->
	        clusterManager.defineCluster(clusterName, cloudToolsService.makeClusterSpec("cloudtools"));
	        clusterManager.startCluster(clusterName);
	    }
	}
	
	void tearDown(){
		//stop cluster
		cloudToolsService.withCluster{clusterManager, clusterName, cluster ->
	        cluster.stop()
	        clusterManager.removeCluster(clusterName)
	    }
	}
	
	void testMultipleTiers(){
		//test enable master backups
		def result = executeGrailsCommand("cloud-tools-enable-master-backups", null)
		assertExitValue(0, result);
	    assertStdOut("Done enabling master backups", result);
	
		//test bad enable-slave-backups
		result = executeGrailsCommand("cloud-tools-enable-slave-backups", null)
		assertExitValue(0, result);
	    assertStdErr("cloudtools.slave was not specified", result);
		
		def slaveId = null
		cloudToolsService.withCluster{clusterManager, clusterName, cluster ->
		        slaveId = cluster.clusterInstance.databaseTier.mySqlSlaves[0].host.instanceId
		}
		
		//test enable-slave-backups
		result = executeGrailsCommand("-Dcloudtools.slave=$slaveId cloud-tools-enable-slave-backups", null)
		assertExitValue(0, result);
	    assertStdOut("Done backing up", result);
	
		//test jmeter fail
		result = executeGrailsCommand("cloud-tools-jmeter", null)
		assertExitValue(0, result);
	    assertStdErr("You did not specify 'cloudtools.jmxTestFile'", result);
	
		//test jmeter (doesn't work yet)
		createJMXFile()
		result = executeGrailsCommand("-Dcloudtools.jmxTestFile=./explodedWar/test.jmx cloud-tools-jmeter", null)
		assertEquals(0, result.getExitValue());
	    assertStdOut("JMeter Testing", result);
	
		//test stopping JMeter
		result = executeGrailsCommand("cloud-tools-stop-jmeter", null)
		assertExitValue(0, result);
	    assertStdOut("Stopped JMeter", result);
	
		//test stop-mysql-slave
		result = executeGrailsCommand("-Dcloudtools.slave=$slaveId cloud-tools-stop-mysql-slave", null)
		assertExitValue(0, result);
	    assertStdOut("Slave Stopped", result);
	
	}
	
	//this is the simplest jmx file I can create.
	private void createJMXFile(){
		def jmx = """
		<jmeterTestPlan version="1.2" properties="1.8">
		  <hashTree>
		    <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan" enabled="true">
		      <elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
		        <collectionProp name="Arguments.arguments"/>
		      </elementProp>
		      <stringProp name="TestPlan.user_define_classpath"></stringProp>
		      <boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
		      <boolProp name="TestPlan.functional_mode">false</boolProp>
		      <stringProp name="TestPlan.comments"></stringProp>
		    </TestPlan>
		    <hashTree>
		      <ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Thread Group" enabled="true">
		        <longProp name="ThreadGroup.start_time">1176770410000</longProp>
		        <stringProp name="ThreadGroup.delay"></stringProp>
		        <stringProp name="ThreadGroup.duration"></stringProp>
		        <stringProp name="ThreadGroup.num_threads">\${threadCount}</stringProp>
		        <boolProp name="ThreadGroup.scheduler">false</boolProp>
		        <elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
		          <stringProp name="LoopController.loops">\${iterations}</stringProp>
		          <boolProp name="LoopController.continue_forever">false</boolProp>
		        </elementProp>
		        <longProp name="ThreadGroup.end_time">1176770410000</longProp>
		        <stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
		        <stringProp name="ThreadGroup.ramp_time">\${rampUpTime}</stringProp>
		      </ThreadGroup>
		      <hashTree>
		        <ConfigTestElement guiclass="HttpDefaultsGui" testclass="ConfigTestElement" testname="HTTP Request Defaults" enabled="true">
		          <stringProp name="HTTPSampler.path"></stringProp>
		          <stringProp name="HTTPSampler.domain">\${host}</stringProp>
		          <stringProp name="HTTPSampler.protocol">http</stringProp>
		          <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
		            <collectionProp name="Arguments.arguments"/>
		          </elementProp>
		          <stringProp name="HTTPSampler.port">\${port}</stringProp>
		        </ConfigTestElement>
		        <hashTree/>
		        <HTTPSampler guiclass="HttpTestSampleGui" testclass="HTTPSampler" testname="homepage" enabled="true">
		          <stringProp name="HTTPSampler.path">/testwebapp</stringProp>
		          <stringProp name="HTTPSampler.method">GET</stringProp>
		          <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
		          <stringProp name="HTTPSampler.protocol"></stringProp>
		          <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
		          <stringProp name="HTTPSampler.port">\${port}</stringProp>
		          <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" enabled="true">
		            <collectionProp name="Arguments.arguments"/>
		          </elementProp>
		          <stringProp name="HTTPSampler.mimetype"></stringProp>
		          <stringProp name="HTTPSampler.FILE_FIELD"></stringProp>
		          <stringProp name="HTTPSampler.monitor">false</stringProp>
		          <stringProp name="HTTPSampler.domain"></stringProp>
		          <stringProp name="HTTPSampler.FILE_NAME"></stringProp>
		          <boolProp name="HTTPSampler.auto_redirects">true</boolProp>
		        </HTTPSampler>
		        <hashTree>
		          <HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="Browser-derived headers" enabled="true">
		            <collectionProp name="HeaderManager.headers">
		              <elementProp name="" elementType="Header">
		                <stringProp name="Header.value">gzip,deflate</stringProp>
		                <stringProp name="Header.name">Accept-Encoding</stringProp>
		              </elementProp>
		              <elementProp name="" elementType="Header">
		                <stringProp name="Header.value">en-us,en;q=0.5</stringProp>
		                <stringProp name="Header.name">Accept-Language</stringProp>
		              </elementProp>
		              <elementProp name="" elementType="Header">
		                <stringProp name="Header.value">ISO-8859-1,utf-8;q=0.7,*;q=0.7</stringProp>
		                <stringProp name="Header.name">Accept-Charset</stringProp>
		              </elementProp>
		              <elementProp name="" elementType="Header">
		                <stringProp name="Header.value">Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3</stringProp>
		                <stringProp name="Header.name">User-Agent</stringProp>
		              </elementProp>
		              <elementProp name="" elementType="Header">
		                <stringProp name="Header.value">text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5</stringProp>
		                <stringProp name="Header.name">Accept</stringProp>
		              </elementProp>
		              <elementProp name="" elementType="Header">
		                <stringProp name="Header.value">300</stringProp>
		                <stringProp name="Header.name">Keep-Alive</stringProp>
		              </elementProp>
		            </collectionProp>
		          </HeaderManager>
		          <hashTree/>
		        </hashTree>
		        <ResultCollector guiclass="StatVisualizer" testclass="ResultCollector" testname="Aggregate Report" enabled="true">
		          <objProp>
		            <value class="SampleSaveConfiguration">
		              <time>true</time>
		              <latency>true</latency>
		              <timestamp>true</timestamp>
		              <success>true</success>
		              <label>true</label>
		              <code>true</code>
		              <message>true</message>
		              <threadName>true</threadName>
		              <dataType>true</dataType>
		              <encoding>false</encoding>
		              <assertions>true</assertions>
		              <subresults>true</subresults>
		              <responseData>false</responseData>
		              <samplerData>false</samplerData>
		              <xml>false</xml>
		              <fieldNames>false</fieldNames>
		              <responseHeaders>false</responseHeaders>
		              <requestHeaders>false</requestHeaders>
		              <responseDataOnError>false</responseDataOnError>
		              <saveAssertionResultsFailureMessage>false</saveAssertionResultsFailureMessage>
		              <assertionsResultsToSave>0</assertionsResultsToSave>
		            </value>
		            <name>saveConfig</name>
		          </objProp>
		          <stringProp name="filename"></stringProp>
		          <boolProp name="ResultCollector.error_logging">false</boolProp>
		        </ResultCollector>
		        <hashTree/>
		        <ResultCollector guiclass="AssertionVisualizer" testclass="ResultCollector" testname="Assertion Results" enabled="true">
		          <objProp>
		            <value class="SampleSaveConfiguration">
		              <time>true</time>
		              <latency>true</latency>
		              <timestamp>true</timestamp>
		              <success>true</success>
		              <label>true</label>
		              <code>true</code>
		              <message>true</message>
		              <threadName>true</threadName>
		              <dataType>true</dataType>
		              <encoding>false</encoding>
		              <assertions>true</assertions>
		              <subresults>true</subresults>
		              <responseData>false</responseData>
		              <samplerData>false</samplerData>
		              <xml>false</xml>
		              <fieldNames>false</fieldNames>
		              <responseHeaders>false</responseHeaders>
		              <requestHeaders>false</requestHeaders>
		              <responseDataOnError>false</responseDataOnError>
		              <saveAssertionResultsFailureMessage>false</saveAssertionResultsFailureMessage>
		              <assertionsResultsToSave>0</assertionsResultsToSave>
		            </value>
		            <name>saveConfig</name>
		          </objProp>
		          <stringProp name="filename"></stringProp>
		          <boolProp name="ResultCollector.error_logging">false</boolProp>
		        </ResultCollector>
		        <hashTree/>
		        <CookieManager guiclass="CookiePanel" testclass="CookieManager" testname="HTTP Cookie Manager" enabled="true">
		          <boolProp name="CookieManager.clearEachIteration">false</boolProp>
		          <collectionProp name="CookieManager.cookies"/>
		        </CookieManager>
		        <hashTree/>
		        <Arguments guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
		          <collectionProp name="Arguments.arguments">
		            <elementProp name="threadCount" elementType="Argument">
		              <stringProp name="Argument.metadata">=</stringProp>
		              <stringProp name="Argument.value">\${__P(threadCount,3)}</stringProp>
		              <stringProp name="Argument.name">threadCount</stringProp>
		            </elementProp>
		            <elementProp name="rampUpTime" elementType="Argument">
		              <stringProp name="Argument.metadata">=</stringProp>
		              <stringProp name="Argument.value">\${__P(rampUpTime,3)}</stringProp>
		              <stringProp name="Argument.name">rampUpTime</stringProp>
		            </elementProp>
		            <elementProp name="iterations" elementType="Argument">
		              <stringProp name="Argument.metadata">=</stringProp>
		              <stringProp name="Argument.value">\${__P(iterations,10000)}</stringProp>
		              <stringProp name="Argument.name">iterations</stringProp>
		            </elementProp>
		            <elementProp name="host" elementType="Argument">
		              <stringProp name="Argument.metadata">=</stringProp>
		              <stringProp name="Argument.value">\${__P(host,&quot;localhost&quot;)}</stringProp>
		              <stringProp name="Argument.name">host</stringProp>
		            </elementProp>
		            <elementProp name="port" elementType="Argument">
		              <stringProp name="Argument.metadata">=</stringProp>
		              <stringProp name="Argument.value">\${__P(port,8080)}</stringProp>
		              <stringProp name="Argument.name">port</stringProp>
		            </elementProp>
		          </collectionProp>
		        </Arguments>
		        <hashTree/>
		        <ResultSaver guiclass="ResultSaverGui" testclass="ResultSaver" testname="Save Responses to a file" enabled="true">
		          <stringProp name="FileSaver.filename">fail</stringProp>
		          <stringProp name="FileSaver.errorsonly">true</stringProp>
		        </ResultSaver>
		        <hashTree/>
		      </hashTree>
		    </hashTree>
		  </hashTree>
		</jmeterTestPlan>
		"""
		
		def file = new File("explodedWar/")
		file.mkdirs()
		new File(file, "test.jmx").withWriter{out -> out << jmx}
	}
	
}